<template>
	<view class="content">
		<view class="main">
			<!-- 主天气卡片 -->
			<view class="weather-card">
				<view class="weather-content" v-if="weatherData">
					<view class="weather-left">
						<image 
						  :src='"/static/QWeather-Icons-1.7.0/icons/" + weatherData.now.icon + ".svg"'
						  class="weather-icon"
						></image>
						<text class="weather-text">{{weatherData.now.text}}</text>
						<text class="weather-date">{{formatDate(new Date())}}</text>
					</view>
					<view class="weather-right">
						<text class="location">湘潭市 · 岳塘区</text>
						<text class="temperature">{{weatherData.now.temp}}°C</text>
						<text class="feels-like">体感温度 {{weatherData.now.feelsLike}}°C</text>
					</view>
				</view>
				<view class="loading" v-else>
					<text>加载天气数据中...</text>
					<view class="loading-spinner"></view>
				</view>
			</view>
			
			<!-- 5小时预报卡片 -->
			<view class="forecast-card">
				<view class="hourly-forecast">
					<view class="hour-item" v-for="(item,index) in weather5hData" :key="index">
						<text class="hour">{{formatHour(item.fxTime)}}</text>
						<image
						  :src='"/static/QWeather-Icons-1.7.0/icons/" + item.icon + ".svg"'
						  class="hour-icon"
						></image>
						<text class="hour-temp">{{item.temp}}°C</text>
					</view>
				</view>
			</view>
			
			<!-- 数据卡片 -->
			<view  v-if="data" class="data-card">
			    <view class="card-header">
			        <text class="card-title">健康与环境数据</text>
			        <text class="card-subtitle">实时监测 · 精准记录</text>
			    </view>
			    <view class="data-grid">
			        <!-- 第一行 -->
			        <view class="data-item elevation">
			            <view class="data-icon-bg" style="background-color: #e3f2fd;">
			                <image src="/static/icons/hjwd.png" class="data-icon"></image>
			            </view>
			            <text class="data-value">{{data.hjwd.data}}°C</text>
			            <text class="data-label">环境温度</text>
			            <view class="data-trend" v-if="data.hjwd.trend > 0">
			                <text class="trend-text">+{{data.hjwd.trend}}°C</text>
			                <image src="/static/icons/up.png" class="trend-icon"></image>
			            </view>
						<view class="data-trend" v-else-if="data.hjwd.trend === 0">
							<text class="trend-text">无变化</text>
						</view>
						<view class="data-trend" style="color: rgb(93, 185, 131);" v-else>
							<text class="trend-text">{{data.hjwd.trend}}°C</text>
							<image src="/static/icons/down.png" class="trend-icon"></image>
						</view>
			        </view>
			        
			        <view class="data-item elevation">
			            <view class="data-icon-bg" style="background-color: #e8f5e9;">
			                <image src="/static/icons/sd.png" class="data-icon"></image>
			            </view>
			            <text class="data-value">{{data.sd.data}}</text>
			            <text class="data-label">环境湿度</text>
			            <view class="data-trend" v-if="data.sd.trend > 0">
							<text class="trend-text">+{{data.sd.trend}}</text>
							<image src="/static/icons/up.png" class="trend-icon"></image>
						</view>
						<view class="data-trend" v-else-if="data.sd.trend === 0">
							<text class="trend-text">无变化</text>
						</view>
						<view class="data-trend" style="color: rgb(93, 185, 131);" v-else>
							<text class="trend-text">{{data.sd.trend}}</text>
							<image src="/static/icons/down.png" class="trend-icon"></image>
						</view>
			        </view>
			        
			        <!-- 第二行 -->
			        <view class="data-item elevation">
			            <view class="data-icon-bg" style="background-color: #ffebee;">
			                <image src="/static/icons/xl.png" class="data-icon"></image>
			            </view>
			            <text class="data-value">{{data.xl.data}}</text>
			            <text class="data-label">心率</text>
			            <view class="data-trend">
			                <text class="trend-text">{{data.xl.judge}}</text> 
			            </view>
			        </view>
			        
			        <view class="data-item elevation">
			            <view class="data-icon-bg" style="background-color: #e8eaf6;">
			                <image src="/static/icons/xy.png" class="data-icon"></image>
			            </view>
			            <text class="data-value">{{data.xy.data}}</text>
			            <text class="data-label">血氧</text>
			            <view class="data-trend">
			                <text class="trend-text">{{data.xy.judge}}</text> 
			            </view>
			        </view>
			        
			        <!-- 第三行 -->
			        <view class="data-item elevation">
			            <view class="data-icon-bg" style="background-color: #fff3e0;">
			                <image src="/static/icons/rtwd.png" class="data-icon"></image>
			            </view>
			            <text class="data-value">{{data.rtwd.data}}°C</text>
			            <text class="data-label">人体温度</text>
			            <view class="data-trend">
			                <text class="trend-text">{{data.rtwd.judge}}</text>
			            </view>
			        </view>
			        
			        <view class="data-item elevation" @click="showTirePressureDialog">
			            <view class="data-icon-bg" style="background-color: #f3e5f5;">
			                <image src="/static/icons/ty.png" class="data-icon"></image>
			            </view>
			            <text class="data-value">{{data.ty.data}}Bar</text>
			            <text class="data-label">胎压</text>
			            <view class="data-trend">
			                <text class="trend-text">{{data.ty.judge}}</text>
			            </view>
			        </view>
			        
			        <!-- 骑行速度单独一行 -->
			        <view class="data-item-full elevation">
			            <view class="speed-content">
			                <view class="speed-icon-container">
			                    <image src="/static/icons/qx.png" class="speed-icon"></image>
			                </view>
			                <view class="speed-info">
			                    <text class="data-label">骑行速度</text>
			                    <text class="data-value">{{data.qxsd.data}}km/h</text>
			                </view>
			                <view class="speed-stats">
			                    <view class="stat-item">
			                        <text class="stat-value">{{data.qxsd.avg}}</text>
			                        <text class="stat-label">平均速度</text>
			                    </view>
			                    <view class="stat-item">
			                        <text class="stat-value">{{data.qxsd.max}}</text>
			                        <text class="stat-label">最高速度</text>
			                    </view>
			                </view>
			            </view>
			            <view class="progress-container">
			                <view class="progress-bar" :style=data.qxsd.bai></view>
			            </view> 
			        </view>
			    </view>
			</view>
			<!-- 设备卡片 -->
			<view class="device-card">
				<view class="card-header">
					<text class="card-title">设备控制</text>
					<text class="card-subtitle">实时连接 · 智能操控</text>
				</view>
				
				<view class="device-grid">
					<!-- 安全眼 -->
					<view class="device-item elevation" @click="toggleDevice('safetyEye')">
						<view class="device-icon-container" :style="{backgroundColor: devices.safetyEye.on ? '#e3f2fd' : '#f5f5f5'}">
							<image src="/static/icons/eye.png" class="device-icon" 
								  :style="{filter: devices.safetyEye.on ? 'none' : 'grayscale(100%) opacity(0.6)'}"></image>
						</view>
						<text class="device-name">安全眼</text>
						<text class="device-status" :style="{color: devices.safetyEye.on ? '#4caf50' : '#f44336'}">
							{{devices.safetyEye.on ? '实时查看' : '未查看'}} 
						</text>
						<view class="device-toggle" :class="{'active': devices.safetyEye.on}">
							<view class="toggle-circle"></view>
						</view>
					</view>
					
					<!-- 车灯 -->
					<view class="device-item elevation" @click="toggleDevice('deng')">
						<view class="device-icon-container" :style="{backgroundColor: devices.deng.on ? '#fff8e1' : '#f5f5f5'}">
							<image src="/static/icons/deng.png" class="device-icon"
								  :style="{filter: devices.deng.on ? 'none' : 'grayscale(100%) opacity(0.6)'}"></image>
						</view>
						<text class="device-name">车灯</text>
						<text class="device-status" :style="{color: devices.deng.on ? '#4caf50' : '#f44336'}">
							{{devices.deng.on ? '开启' : '关闭'}}
						</text>
						<view class="device-toggle" :class="{'active': devices.deng.on}">
							<view class="toggle-circle"></view>
						</view>
					</view>
					
					<!-- 车锁 -->
					<view class="device-item elevation" @click="toggleDevice('lock')">
						<view class="device-icon-container" :style="{backgroundColor: devices.lock.on ? '#e8f5e9' : '#f5f5f5'}">
							<image src="/static/icons/suo.png" class="device-icon"
								  :style="{filter: devices.lock.on ? 'none' : 'grayscale(100%) opacity(0.6)'}"></image>
						</view>
						<text class="device-name">车锁</text>
						<text class="device-status" :style="{color: devices.lock.on ? '#4caf50' : '#f44336'}">
							{{devices.lock.on ? '已解锁' : '锁定'}}
						</text>
						<view class="device-toggle" :class="{'active': devices.lock.on}">
							<view class="toggle-circle"></view>
						</view>
					</view>
				</view>
			</view>
		</view>
		<uni-popup ref="tirePressurePopup" type="dialog">
		    <view class="threshold-dialog">
		        <text class="dialog-title">设置胎压阈值</text>
		        
		        <view class="input-group">
		            <text class="input-label">最低值 (Bar)</text>
		            <input 
		                class="threshold-input" 
		                type="number" 
		                v-model="tirePressureMin" 
		                placeholder="请输入最低值"
		            />
		        </view>
		        
		        <view class="input-group">
		            <text class="input-label">最高值 (Bar)</text>
		            <input 
		                class="threshold-input" 
		                type="number" 
		                v-model="tirePressureMax" 
		                placeholder="请输入最高值"
		            />
		        </view>
		        
		        <view class="dialog-buttons">
		            <button class="dialog-button cancel" @click="closeTirePressureDialog">取消</button>
		            <button class="dialog-button confirm" @click="setTirePressureThreshold">确定</button>
		        </view>
		    </view>
		</uni-popup>
		<uni-popup ref="safetyEyePopup" type="center" :mask-click="false">
			<view class="video-popup">
				<view class="popup-header">
					<text class="popup-title">安全眼实时监控</text>
					<image 
						style="margin-top: 5px;margin-left: 180px;"
						src="/static/icons/close.png" 
						class="close-icon" 
						@click="closeSafetyEye"
					></image>
				</view>
				<view class="video-container">
					<image 
						:src="streamImageUrl" 
						class="video-frame"
						v-if="streamImageUrl"
						mode="aspectFit"
						@error="handleStreamError" 
					></image>
					<view class="loading-video" v-else>
						<text>正在连接视频流...</text>
						<view class="loading-spinner"></view>
					</view>
				</view>
				<view class="popup-footer">
					<text class="timestamp">{{currentTimestamp}}</text>
				</view>
			</view>
		</uni-popup>
	</view>
</template>
 
<script>
	import Weather from '../../utils/Weather.js'
	import GaoDe from '../../utils/GaoDe.js'
	export default {
		data() {
			return {
				weatherData: null,
				loading: true,
				weather5hData: null,
				city: "",
				devices: {
					safetyEye: {
						on: false,
						name: '安全眼'
					},
					deng: {
						on: false,
						name: '车灯'
					},
					lock: {
						on: true,
						name: '车锁'
					}
				},
				data:null,
				mqttWs:null,
				flag :false,
				tirePressureThreshold: "800-1000",
				tirePressureMin: "", 
				tirePressureMax: "",
				streamImageUrl: '', // 视频流地址
				currentTimestamp: '', // 当前时间戳
				streamInterval: null, // 视频流轮询定时器
				videoStreamUrl: 'http://192.168.166.204:5000',
				streamRefreshRate: 200 
			}
		},
		async onShow() {
			console.log('show')
			this.getWeatherData()
			this.getWeather5hData()
			this.sendWs()
			if(!this.mqttWs){
				setTimeout(()=>{
					this.mqtt()
				},500)
			}
		},
		onHide(){
			if(this.mqttWs){
				this.mqttWs.close({
					success: () => {
						console.log('更新连接关闭')
					},
					fail: () => {
						console.log('更新连接关闭失败')
					}
				})
				this.mqttWs = null
			}
		},
		methods: {
			showTirePressureDialog() {
			        // 初始化输入框值为当前阈值
			        if (this.tirePressureThreshold) {
			            const [min, max] = this.tirePressureThreshold.split('-');
			            this.tirePressureMin = min;
			            this.tirePressureMax = max;
			        }
			        this.$refs.tirePressurePopup.open();
			},
			closeTirePressureDialog() {
					this.$refs.tirePressurePopup.close();
			},
			setTirePressureThreshold() {
					const min = parseFloat(this.tirePressureMin);
					const max = parseFloat(this.tirePressureMax);
					
					// 验证输入
					if (isNaN(min) || isNaN(max)) {
						uni.showToast({
							title: '请输入有效数字',
							icon: 'none'
						});
						return;
					}
					
					if (min >= max) {
						uni.showToast({
							title: '最低值必须小于最高值',
							icon: 'none'
						});
						return;
					}
					
					this.tirePressureThreshold = `${min}-${max}`;
					let url = this.$wsUrl + '/threshold'
					const ws = uni.connectSocket({
						url:url,
						success(){
								console.log(url + ' 连接成功')
						},
						fail(){
							console.log(url + ' 连接失败')
						}
					})
					ws.onOpen(()=>{
						ws.send({
							data:JSON.stringify({
								value:this.tirePressureThreshold
							})
						})
						ws.close({
							success: () => {
								console.log('阈值设置连接关闭')
							},
							fail: () => {
								console.log('阈值设置连接关闭失败')
							}
						})
					})
					this.$refs.tirePressurePopup.close();
					setTimeout(()=>{
						this.sendWs()
					},200)
					uni.showToast({
						title: '胎压阈值设置成功',
						icon: 'success'
					});
			},
			playAudio(type,error){
				const iac = uni.createInnerAudioContext()
				iac.autoplay = true;
				if(type === 'all'){
					iac.src = '/static/mp3/duo.mp3';
				}else{
					if(type === 'rtwd'){
						iac.src = `/static/mp3/rtwd.mp3`;
					}else if(type === 'ty'){
						iac.src = `/static/mp3/ty${error>0?'up':'down'}.mp3`;
					}else if(type === 'xl'){
						iac.src = `/static/mp3/xl.mp3`;
					}else if(type === 'xy'){
						iac.src = `/static/mp3/xy.mp3`;
					}else if(type === 'person'){
						iac.src = `/static/mp3/person.mp3`;
					}else if(type === 'car'){
						iac.src = `/static/mp3/car.mp3`;
					}else if(type === 'truck'){
						iac.src = `/static/mp3/truck.mp3`;
					}
				}
				iac.play()
				iac.onError((res) => {
				        console.log('报警音频播放错误', res.errMsg, res.errCode);
				    });
				setTimeout(()=>{
					iac.destroy()
				},5000)
			},
			mqtt(){
				let url = this.$wsUrl + '/mqtt'
				this.mqttWs = uni.connectSocket({
					url:url,
					success(){
						console.log(url + ' 连接成功')
					},
					fail(){
						console.log(url + ' 连接失败')
					}
				})
				this.mqttWs.onMessage((res)=>{
					let msg = JSON.parse(res.data)
					console.log(msg)
					if(msg.topic === 'sensor_data'){ 
						this.sendWs()
					}else if(msg.topic === 'eye'){
						if(msg.data === true){
							this.devices.safetyEye.on = true
							this.openSafetyEye()
						}else{
							this.devices.safetyEye.on = false
							this.closeSafetyEye()
						}
					}else if(msg.topic === 'yolo'){
						if(msg.data === '"person"' || msg.data === 'person'){
							this.playAudio('person',0)
						}else if(msg.data === '"car"' || msg.data === 'car'){
							this.playAudio('car',0)
						}else if(msg.data === '"truck"' || msg.data === 'truck'){
							this.playAudio('truck',0)
						}
					}else if(msg.topic === 'deng'){
						if(msg.data === 'open'){
							this.devices.deng.on = true
						}else if(msg.data === 'close'){
							this.devices.deng.on = false
						}
					}
				})
			},
			async sendWs(){
				let result = await new Promise(res => {
					let url = this.$wsUrl + '/single'
					let ws = uni.connectSocket({
						url:url,
						success(){
							console.log(url + ' 连接成功')
						},
						fail(){
							console.log(url + ' 连接失败')
						}				
					})
					ws.onMessage((e)=>{
						res(JSON.parse(e.data))
						ws.close({
							success(){
									console.log(url + '关闭成功')
								},
								fail(){
									console.log(url + '关闭失败')
								}
						})
					})
				})
				this.data = result.data
				this.tirePressureThreshold = result.tyThreshold
				let type = ''
				let error = 0
				let count = 0
				for(let i in this.data){
					if(this.data[i]['error']){
						count += 1
						if(count > 1)break
						type = i
						error = this.data[i]['error']
					}
				}
				if(count > 1){
					this.playAudio('all',0)
				}else if(count === 1){
					this.playAudio(type,error)
				}
			},
			async getWeatherData() {
				try { 
					const gps = await this.gaode()
					const weather = new Weather(gps)
					const res = await weather.getWeather()
					
					if(res.statusCode === 200) {
						this.weatherData = res.data
					} else {
						this.showError()
					}
				} catch (error) {
					console.log(error)
					this.showError()
				} finally {
					this.loading = false
				}
			},
			async getWeather5hData() {
				try {
					const gps = await this.gaode()
					const weather = new Weather(gps)
					const res = await weather.get24hWeather()
					this.weather5hData = res.data.hourly.slice(0, 5)
				} catch (error) {
					console.log(error)
				}
			},
			showError() {
				uni.showToast({
					title: '获取天气失败',
					icon: 'error'
				})
			},
			formatDate(date) {
				const options = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }
				return date.toLocaleDateString('zh-CN', options)
			},
			formatHour(timeString) {
				return timeString.split('T')[1].substring(0, 5)
			},
			async gaode() {
				const gaode = new GaoDe()
				const r = await gaode.getLocation()
				this.city = r.address.city + ' · ' + r.address.district
				return r.address.province + r.address.city + r.address.district
			},
			toggleDevice(device) {
				this.devices[device].on = !this.devices[device].on;
				if(device !== 'safetyEye'){
					let url = this.$wsUrl + '/direct'
					const ws = uni.connectSocket({
						url:url,
						success(){
							console.log(url + "连接成功")
						},
						fail(){
							console.log(url + "连接失败")
						}
					})
					ws.onOpen(()=>{
						ws.send({
							data:JSON.stringify({
								type:device,
								value:this.devices[device].on ? 'open':'close'
							})
						})
						ws.close({
							success(){
								console.log(url + '关闭成功')
							},
							fail(){
								console.log(url + '关闭失败')
							}
						})
					})
				}else{
					if(this.devices[device].on) {
						this.openSafetyEye();
					} else {
						this.closeSafetyEye();
					}
				}
				uni.showToast({
					title: `${this.devices[device].name}已${this.devices[device].on ? '开启' : '关闭'}`,
					icon: 'none'
				});
			},
			openSafetyEye() {
				// 打开弹窗
				this.$refs.safetyEyePopup.open();
				
				// 开始获取视频流
				this.startVideoStream();
			},
			
			closeSafetyEye() {
				// 关闭弹窗
				this.$refs.safetyEyePopup.close();
				
				// 停止视频流
				this.stopVideoStream();
				
				// 更新设备状态
				this.devices.safetyEye.on = false;
			},
			
			startVideoStream() {
			    // 清除可能存在的旧定时器
			    if (this.streamInterval) {
			      clearInterval(this.streamInterval);
			      this.streamInterval = null;
			    }
			    // 直接设置流地址（MJPEG流会通过一次连接持续返回帧，无需轮询）
			    this.streamImageUrl = this.videoStreamUrl;
			    // 定时更新时间戳显示（仅用于UI展示，不影响流加载）
			    this.streamInterval = setInterval(() => {
			      this.currentTimestamp = new Date().toLocaleTimeString();
			    }, this.streamRefreshRate);
			  },
			
			stopVideoStream() {
				if (this.streamInterval) {
				  clearInterval(this.streamInterval);
				  this.streamInterval = null;
				}
				this.streamImageUrl = '';  // 清空流地址，停止显示
			  },
			handleStreamError(e) {
			  console.error('视频流加载失败：', e);
			  uni.showToast({ title: '视频流加载失败', icon: 'none' });
			}
		} 
	}
</script>

<style scoped>
	/* 数据卡片样式 */
	@import '../../css/index_data.css'; 
	/* 天气卡片样式 */
	@import '../../css/index_weather.css';  
	/* 设备卡片样式 */
	@import '../../css/index_device.css';
	.content {
		width: 100%;
		display: flex;
		justify-content: center;
		padding: 20rpx;
		box-sizing: border-box;
		background: linear-gradient(to bottom, #f5f7fa 0%, #e4e8eb 100%);
		min-height: 100vh;
	}
	 
	.main {
		width: 100%;
		max-width: 710rpx;
		display: flex;
		flex-direction: column;
		gap: 24rpx;
	}
	
	.video-popup {
		width: 95vw;
		max-width: 710rpx;
		background-color: #fff;
		border-radius: 16rpx;
		overflow: hidden;
		box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.2);
	}
	
	.popup-header {
		padding: 20rpx;
		background-color: #2196F3;
		flex-direction: row;
		justify-content: space-between;
		align-items: center;
	}
	
	.popup-title {
		color: white;
		font-size: 32rpx;
		font-weight: bold;
	}
	
	.close-icon {
		width: 40rpx;
		height: 40rpx;
	}
	
	.video-container {
		width: 710rpx;
		height: 600rpx;
		background-color: #000;
		justify-content: center;
		align-items: center;
	}
	
	.video-frame {
		width: 100%;
		height: 100%;
	}
	
	.loading-video {
		flex-direction: column;
		align-items: center;
		gap: 20rpx;
	}
	
	.loading-video text {
		color: white;
		font-size: 28rpx;
	}
	
	.popup-footer {
		padding: 16rpx;
		background-color: #f5f5f5;
		align-items: flex-end;
	}
	
	.timestamp {
		font-size: 24rpx;
		color: #666;
	}
	
	.loading-spinner {
		width: 40rpx;
		height: 40rpx;
		border: 4rpx solid rgba(255, 255, 255, 0.3);
		border-radius: 50%;
		border-top-color: #3498db;
		animation: spin 1s ease-in-out infinite;
	}
	
	@keyframes spin {
		to { transform: rotate(360deg); }
	}
</style>